"""
@Author  : 康帅
@Time    : 2021/3/23 11:23
@Function: 组合模式：电脑组装
"""

# ABCMeta和abstractmethod是用来抽象类和方法
from abc import ABCMeta, abstractmethod


class ComputerComponent(metaclass=ABCMeta):
    """ 组件，所有子配件的基类 """

    def __init__(self, name):
        self._name = name

    @abstractmethod
    def show_info(self, ident):
        pass

    def is_composite(self):
        return False

    def start_up(self, ident):
        print(f"{ident}{self._name}准备开始工作...")

    def shut_down(self, ident):
        print(f"{ident}{self._name}即将结束工作...")


class CPU(ComputerComponent):
    """ 中央处理器 """

    def __init__(self, name):
        super().__init__(name)

    def show_info(self, ident):
        print(f"{ident}CPU:{self._name}可以进行高速计算。")


class MemoryCard(ComputerComponent):
    """ 内存条 """

    def __init__(self, name):
        super().__init__(name)

    def show_info(self, ident):
        print(f"{ident}内存条:{self._name}可以缓存数据读写速度比较快。")


class HardDisk(ComputerComponent):
    """ 硬盘 """

    def __init__(self, name):
        super().__init__(name)

    def show_info(self, ident):
        print(f"{ident}硬盘:{self._name}可以永久存储数据。")


class GraphicsCard(ComputerComponent):
    """ 显卡 """

    def __init__(self, name):
        super().__init__(name)

    def show_info(self, ident):
        print(f"{ident}显卡:{self._name}可以高效计算图像。")


class Battery(ComputerComponent):
    """ 电源 """

    def __init__(self, name):
        super().__init__(name)

    def show_info(self, ident):
        print(f"{ident}电源:{self._name}可以为计算机提供电。")


class Fan(ComputerComponent):
    """ 风扇 """

    def __init__(self, name):
        super().__init__(name)

    def show_info(self, ident):
        print(f"{ident}风扇:{self._name}可以为计算机散热。")


class Display(ComputerComponent):
    """ 显示器 """

    def __init__(self, name):
        super().__init__(name)

    def show_info(self, ident):
        print(f"{ident}显示器:{self._name}可以为计算机提供画面显示。")


class ComputerComposite(ComputerComponent):
    """ 组合配件 """

    def __init__(self, name):
        super().__init__(name)
        self._components = []

    def show_info(self, ident):
        print(f"{self._name}由以下部件组成:")
        ident += "\t"
        for element in self._components:
            element.show_info(ident)

    def is_composite(self):
        return True

    def add_component(self, component):
        self._components.append(component)

    def remove_component(self, component):
        self._components.append(component)

    def start_up(self, ident):
        super().start_up(ident)
        ident += "\t"
        for element in self._components:
            element.start_up(ident)

    def shut_down(self, ident):
        super().shut_down(ident)
        ident += "\t"
        for element in self._components:
            element.shut_down(ident)


class MainBoard(ComputerComposite):
    """ 主板 """

    def __init__(self, name):
        super().__init__(name)

    def show_info(self, ident):
        print(ident + "主板:", end="")
        super().show_info(ident)


class ComputerCase(ComputerComposite):
    """ 机箱 """

    def __init__(self, name):
        super().__init__(name)

    def show_info(self, ident):
        print(ident + "机箱:", end="")
        super().show_info(ident)


class Compute(ComputerComposite):
    """ 电脑 """

    def __init__(self, name):
        super().__init__(name)

    def show_info(self, ident):
        print(ident + "电脑:", end="")
        super().show_info(ident)


if __name__ == '__main__':
    main_board = MainBoard("GIGABYTE Z170M M-ATX")
    main_board.add_component(CPU("Intel Core i5-6600K"))
    main_board.add_component(MemoryCard("Kingston Fury DDR4"))
    main_board.add_component(HardDisk("Kingston V300"))
    main_board.add_component(GraphicsCard("Colorful iGame750"))

    computer_case = ComputerCase("SAMA MATX")
    computer_case.add_component(main_board)
    computer_case.add_component(Battery("Antec VP 450P"))
    computer_case.add_component(Fan("DEEPCOOL 120T"))

    computer = Compute("Tong diy电脑")
    computer.add_component(computer_case)
    computer.add_component(Display("AOC GT2"))

    computer.show_info("")
    print("\n开机过程：")
    computer.start_up("")
    print("\n关机过程：")
    computer.shut_down("")
